package com.gxitsky.utils;

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Security;

/**
 * 3DES加密工具
 *
 * @Author: jingliang
 * @Date: 2020/7/2
 * @Version: V1
**/
public class DesUtil {

    private DesUtil(){
    }

    public static final String DEFAULT_CHARSET = "UTF-8";
    public static final String DEFAULT_KEY = "rdkIKZR59w7HFfeiT4m6eixSRSNYdpcQ";
    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     * 3DES加密，ECB 模式，Zeros 填充
     *
     * @Param: [data, key]
     * @Return: java.lang.String
     * @Author: jingliang
     * @Date: 2020/8/25
     * @Version: V1
     **/
    public static String enc(String data, String key) throws Exception {
        return Base64.encodeBase64String(encrypt(data.getBytes() ,key));
    }

    /**
     * 3DES解密
     *
     * @Param: [param, key]
     * @Return: java.lang.String
     * @Author: jingliang
     * @Date: 2020/8/25
     * @Version: V1
     **/
    public static String dec(String data, String key) throws Exception {
        return new String(desrypt(Base64.decodeBase64(data) ,key), DEFAULT_CHARSET).trim();
    }

    /**
     * 补足长度
     *
     * @Param: [src, len]
     * @Return: byte[]
     * @Version: V1
    **/
    public static byte[] paddingZero(byte[] src, int len) {
        int paddingLength = len - src.length % len;
        if (len == paddingLength) {
            return src;
        }
        byte[] newsrc = new byte[src.length + paddingLength];
        System.arraycopy(src, 0, newsrc, 0, src.length);
//        System.out.println("补充长度后:");
        for (int i = 0; i < newsrc.length; i++) {
            System.out.printf("%02X", newsrc[i]);
        }
        System.out.println();
        return newsrc;
    }

    /**
     * 3DES加密
     *
     * @Param: [data, desKey]
     * @Return: byte[]
     * @Author: jingliang
     * @Date: 2020/8/29
     * @Version: V1
     **/
    public static byte[] encrypt(byte[] data ,String key) throws Exception {
        SecretKey deskey = new SecretKeySpec(HexUtil.hex2byte(key), "DESede");

        String algorithm = "DESede/ECB/NoPadding";
        Cipher cipher = Cipher.getInstance(algorithm);
        data = paddingZero(data, 8);
        byte[] res = null;
        cipher.init(Cipher.ENCRYPT_MODE, deskey);
        res = cipher.doFinal(data);
        return res;
    }

    /**
     * 3DES解密
     *
     * @Param: [data, desKey]
     * @Return: byte[]
     * @Author: jingliang
     * @Date: 2020/8/29
     * @Version: V1
    **/
    public static byte[] desrypt(byte[] data ,String desKey) throws Exception {
        SecretKey deskey = new SecretKeySpec(HexUtil.hex2byte(desKey), "DESede");

        byte[] res = null;
        String algorithm = "DESede/ECB/NoPadding";
        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.DECRYPT_MODE, deskey);
        res = cipher.doFinal(data);
        return res;
    }

    /**
     * 测试
     *
     * @Param: [args]
     * @Return: void
     * @Author: jingliang
     * @Date: 2020/8/29
     * @Version: V1
    **/
    public static void main(String[] args) throws Exception {
        String testStr = "99988877766";

        String encResult = enc(testStr ,DEFAULT_KEY);
        String decResult = dec(encResult ,DEFAULT_KEY);

        System.err.println("encResult:"+encResult);
        System.err.println("decResult:"+decResult);
    }

}
